package pki;

import org.apache.log4j.Logger;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class TcpTunnel {
    private static Logger logger = Logger.getLogger(TcpTunnel.class);

    public static Properties props;

    public static void main(String[] paramArrayOfString) throws IOException {
        TcpTunnel.props = new Properties();
        props.load(new FileInputStream("config.properties"));


        int listerPort = Integer.parseInt(props.getProperty("listen.port"));
        String httpIp = props.getProperty("http.ip");
        int httpPort = Integer.parseInt(props.getProperty("http.port"));
        String httpsIp = props.getProperty("https.ip");
        int httpsPort = Integer.parseInt(props.getProperty("https.port"));

        int timeOut = Integer.parseInt(props.getProperty("socket.connect.timeout"));
        int soTimeOut = Integer.parseInt(props.getProperty("socket.so.timeout"));

        int coreSize = Integer.parseInt(props.getProperty("threadpool.coresize"));
        int maxSize = Integer.parseInt(props.getProperty("threadpool.maxsize"));
        long keepaliveTime = Long.parseLong(props.getProperty("threadpool.keepalive.time"));

        logger.info(
                " TcpTunnel: ready to rock and roll on port " + listerPort +
                " to [http://" + httpIp + ":" + httpPort + "] or [https://" + httpsIp + ":" + httpsPort + "]");

        ExecutorService executor = new ThreadPoolExecutor(coreSize, maxSize,  keepaliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue(maxSize));
        ServerSocket localServerSocket = new ServerSocket(listerPort);
        for (; ; ) {
            Socket localSocket = localServerSocket.accept();

            int tag = localSocket.getInputStream().read();

            Accepter accepter = null;
            if(tag == 22) {
                // https
                accepter = new Accepter("HTTPS", tag, localSocket, httpsIp, httpsPort, timeOut, soTimeOut);
            } else {
                // http
                accepter = new Accepter("HTTP", tag, localSocket, httpIp, httpPort, timeOut, soTimeOut);
            }

            try {
                executor.execute(accepter);
            } catch (Throwable ex) {
                logger.error(ex);
            }
        }
    }
}
